#include "registerview.h"
#include "libs/controls/toastlabel.h"
#include "libs/core/user/localuser.h"
#include "services/yingceservice.h"
#include "ui_registerview.h"
#include "yingce.h"
#include <QCryptographicHash>
#include <QJsonObject>
#include <QRegularExpression>
#include <QRegularExpressionValidator>

RegisterView::RegisterView(QWidget* parent) : QFrame(parent), ui(new Ui::RegisterView)
{
    ui->setupUi(this);
    ui->name_edit->setMaxLength(32);
    ui->password_edit->setMaxLength(32);
    ui->password_edit->setEchoMode(QLineEdit::Password);
    ui->code_edit->setMaxLength(6);
    ui->code_label->hide();
    ui->code_edit->hide();
    ui->correct_code_label->hide();
    ui->register_button->setEnabled(false);
    ui->register_button->setDefault(true);
    ui->login_button->setProperty("type", "link");
    ui->name_edit->setValidator(
            new QRegularExpressionValidator(QRegularExpression("^[a-zA-Z][a-zA-Z0-9_@-]*$"), this));
    ui->name_edit->setFocus();
    setTabOrder({ ui->name_edit, ui->password_edit, ui->code_edit, ui->register_button,
                  ui->cancel_button, ui->login_button });

    connect(ui->name_edit, &QLineEdit::textChanged, this, &RegisterView::updateButtonStatus);
    connect(ui->password_edit, &QLineEdit::textChanged, this, &RegisterView::updateButtonStatus);
    connect(ui->password_edit, &QLineEdit::returnPressed, ui->register_button, &QPushButton::click);
    connect(ui->register_button, &QPushButton::clicked, this, [this] {
        updateUiStatus(true);
        const QString name = ui->name_edit->text().trimmed();
        const QString code = ui->code_edit->text().trimmed();
        const QString pwd = ui->password_edit->text().trimmed();
        const QString md5pwd = QString::fromUtf8(
                QCryptographicHash::hash(pwd.toUtf8(), QCryptographicHash::Md5).toBase64());
        YingCeService::instance()->registerUser(
                name, md5pwd, code, yc::ResponseHandler(this, &RegisterView::onResponse));
    });
    connect(ui->cancel_button, &QPushButton::clicked, this, &RegisterView::cancelRequested);
    connect(ui->login_button, &QPushButton::clicked, this,
            [this] { Q_EMIT loginRequested(YingCe::instance()->localUser()->name()); });
}

void RegisterView::onResponse(const yc::Request& request, const yc::Response& response)
{
    Q_UNUSED(request)
    if (response.status() != 200) {
        QJsonObject jo = response.data().toObject();
        const QString code = jo["authCode"].toString();
        if (!code.isEmpty()) {
            if (!ui->code_label->isVisibleTo(this)) {
                ui->code_label->show();
                ui->code_edit->show();
                ui->correct_code_label->show();
            }
            ui->correct_code_label->setText(code);
        }
        updateUiStatus(false);
        yc::ToastLabel::showMessage(
                tr("Failed to register a user, the error is \"%1\".").arg(response.msg()), this);
    } else {
        yc::ToastLabel::showMessage(tr("Succeed in registering a user, pls login..."), window());
        Q_EMIT loginRequested(ui->name_edit->text().trimmed());
    }
}

void RegisterView::updateUiStatus(bool busy)
{
    ui->name_edit->setReadOnly(busy);
    ui->password_edit->setReadOnly(busy);
    ui->code_edit->setReadOnly(busy);
    ui->register_button->setEnabled(!busy);
}

void RegisterView::updateButtonStatus()
{
    const QString name = ui->name_edit->text().trimmed();
    const QString pwd = ui->password_edit->text().trimmed();
    const QString code = ui->code_edit->text().trimmed();
    ui->register_button->setEnabled(
            !name.isEmpty() && !pwd.isEmpty()
            && code.compare(ui->correct_code_label->text(), Qt::CaseInsensitive) == 0);
}
